<?php
declare (strict_types=1);

namespace app\command;

use app\common\model\CacheRefreshHandler;
use app\common\service\redis\PoolRedis;
use app\model\AdminDormitory;
use app\model\AdminStudentDormitory;
use think\console\Command;
use think\console\Input;
use think\console\Output;

class FreshCacheWrite extends Command {
    protected function configure(): void {
        // 指令配置
        $this->setName('apiadmin:cacheWrite')->setDescription('自动写入redis');
    }

    /**
     * php think apiadmin:cacheWrite
     * @param Input $input
     * @param Output $output
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\DbException
     * @throws \think\db\exception\ModelNotFoundException
     */
    protected function execute(Input $input, Output $output): void {
        $redis = PoolRedis::instance();

//        $output->info('-----开始执行------');
//        $output->info('-----刷卡数据缓存刷新开始------');
//        $redis->del("smartCards");
//        CacheRefreshHandler::IcCard();
//        CacheRefreshHandler::SimCard();
//        $output->info('-----刷卡数据缓存刷新结束------');
//
//        $output->info('-----学校宿舍数据缓存刷新开始------');
//        AdminDormitory::notExistAndSetAllBySchool(true);
//        $output->info('-----学校宿舍数据缓存刷新结束------');
//
//        $output->info('-----宿舍楼用户统计缓存刷新开始------');
//        AdminDormitory::notExistAndSetAllByUser(true);
//        $output->info('-----宿舍楼用户统计缓存刷新结束------');
//
//        $output->info('-----宿舍号用户编号缓存刷新开始------');
//        CacheRefreshHandler::StudentDorNumber();
//        $output->info('-----宿舍号用户编号缓存刷新结束------');

        $school_id = 36;
        $number_len = 32; // 编号长度
        $delete = true;

        // 超出长度的删除
        $distributionKey = AdminStudentDormitory::NO_KEY;
        $keys = PoolRedis::scanAllForMatch($distributionKey.$school_id.":*:no");
        foreach ($keys as $key) {
            $noAll = $redis->hGetAll($key);
            foreach ($noAll as $index => $item) {
                if ($item >= $number_len){
                    $output->info('超出编号 '.$key.' '.$index.' '.$item);
                    // 删除掉
                    if ($delete){
                        $redis->hDel($key, $index);
                    }
                }
            }
        }
        // 存在重复使用编号
        $distributionKey = AdminStudentDormitory::NO_KEY;
        $keys = PoolRedis::scanAllForMatch($distributionKey.$school_id.":*:no");
        foreach ($keys as $key) {
            $noAll = $redis->hGetAll($key);
            foreach ($noAll as $index => $item) {
                foreach ($noAll as $index1 => $item1) {
                    if ((int)$item1 == $item && $index1 != $index){
                        $output->info('重复编号 '.$key.' '.$index1.' '.$item1);
                        unset($noAll[$index]);
                        // 删除掉
                        if ($delete){
                            $redis->hDel($key, $index1);
                        }
                        // 取一个新的覆盖
//                        $no = (int)$redis->rPop(str_replace(":no", ":pool", $key));
//                        $output->info('写入编号 '.$key.' '.$index1.' '.$no);
//                        $redis->hSet($key, $index1, $no);
                        break;
                    }
                }
            }
        }

        // 重建编号池，已被使用的编号不添加
        if ($delete) {
            $distributionKey = AdminStudentDormitory::NO_KEY;
            $keys = PoolRedis::scanAllForMatch($distributionKey.$school_id.":*:no");
            foreach ($keys as $key) {
                $poolKey = str_replace(":no", ":pool", $key);
                $output->info($key.' '.$poolKey);
                if ($delete) {
                    $redis->del($poolKey);
                }
                $noAll = $redis->hGetAll($key);
                for ($i = 0; $i < $number_len; $i++) {
                    $esic = false;
                    foreach ($noAll as $no) {
                        if ((int)$no == $i) {
                            $esic = true;
                            $output->info('存在 ' . $no);
                            break;
                        }
                    }
                    if ($esic == false) {
                        $output->info('不存在 ' . $i);
                        if ($delete) {
                            $redis->lPush($poolKey, $i);
                        }
                    }
                }
            }
        }

        $output->info('redis写入成功');
    }

}